import './DeviceNodeManagePopUp.scss'
import { ChangeEvent, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"
import {
    Modal, Input, Space, Form, Select,
    Row,
    Col,
    Tabs,
    Upload,
    UploadProps,
    Button,
    Divider,
    Tree,
    Checkbox,
    Empty,
    Tooltip
} from "antd";
import LoadingWapper from "../../../../components/loading/LoadingWapper";
import systemApi from "../../../../api/system";
import { DocConfig, DocInstance, TopicNodeActionType, TopicType } from "../../../../utils/types";
import { addTreePropertyForList, commonErrorMsg, commonSuccessMsg, deepCloneV2, dfsRecursive, dfsRecursiveFromInner, filterTree, findHalfCheckedKeys, generateTreeData, getChangeEventValue, getCheckBoxChangeEventValue, handleJumpEditPage, isEmpty, swapListElements, toastShort, tree2List } from "../../../../utils";
import { DownOutlined, ExclamationCircleOutlined, PartitionOutlined, PlusCircleOutlined, PlusCircleTwoTone, QuestionCircleOutlined } from '@ant-design/icons';
import { generateDocInstance } from '../../word-editor/editor-doc-item-generate';
import { useLocation } from 'react-router-dom';
import TopicTreeContextMenu from '../../../../components/context-menu/TopicTreeContextMenu';
import AddTopicMoal from './AddTopicMoal';
import ReNameTopicModal from './ReNameTopicModal';


interface Props {
    onHandleClose?: Function
    onFinish?: Function
}

const {
    Search
} = Input;

const DeviceNodeManageModalV2 = (props: Props, ref: any) => {
    useImperativeHandle(ref, () => ({
        openModal: openModal,
    }));

    const {
        onFinish,
        onHandleClose
    } = props;

    const [isModalOpen, setIsModalOpen] = useState(false);
    const [submitLoading, setSubmitLoading] = useState(false);
    const [pageLoading, setPageLoading] = useState(false);

    const [topicList, setTopicList] = useState<TopicType[]>([]);
    const [topicSearchValue, setTopicSearchValue] = useState("");
    const [filteredTopicTree, setFilteredTopicTree] = useState<TopicType[]>([]);
    const [currentSelectedTopicNode, setCurrentSelectedTopicNode] = useState<TopicType>(null);
    const [currentHighLightTopicNode, setCurrentHighLightTopicNode] = useState<TopicType>(null)

    const [filteredTreeExpandedKeys, setFilteredTreeExpandedKeys] = useState<string[]>([]);
    const [topicTreeExpandedKeys, setTopicTreeExpandedKeys] = useState<string[]>([]);

    const [tabKey, setTabKey] = useState<'selected' | 'all'>('selected');

    const tempComDocInstance = useRef<DocInstance>(null);
    const tempComDocConfig = useRef<DocConfig>(null);

    const topicTreeSelectNodeIdList = useRef<string[]>([]);

    //树组件的选择id（强校验）
    const [topicTreeCheckedNodeIdList, setTopicTreeCheckedNodeIdList] = useState<string[]>([]);

    const [deviceTopicSearchValue, setDeviceTopicSearchValue] = useState<string>('');
    const [currentDocId, setCurrentDocId] = useState('');
    const [currentType, setCurrentType] = useState<'docId' | 'topicList'>('docId');
    const routerLocation = useLocation();

    const contextMenuRef = useRef(null);

    const [currentTreeNodeActionType, setCurrentTreeNodeActionType] = useState<TopicNodeActionType>(null);

    const addTopicModalRef = useRef<any>(null);
    const renameTopicModalRef = useRef<any>(null);
    const deviceNodeManagePopUpRef = useRef<any>(null);
    const deviceNodeManageModalRef = useRef<any>(null);

    useEffect(() => {
        if (!isModalOpen) {
            setTopicList([]);
            setCurrentSelectedTopicNode(null);
            setTopicSearchValue("");
            setDeviceTopicSearchValue("");
            setTopicTreeCheckedNodeIdList([]);
            setFilteredTreeExpandedKeys([]);
            setCurrentHighLightTopicNode(null);
        }
    }, [isModalOpen]);

    const handleConfirm = () => {
        if (currentType == 'docId') {
            setSubmitLoading(true);
            let _tempComDocInstance = tempComDocInstance.current;
            let tempTopicList = [];
            topicList.forEach(topic => {
                let tempTopic: TopicType = deepCloneV2(topic);
                if (
                    tempTopic.topicSlateDocItemList &&
                    tempTopic.topicSlateDocItemList.length &&
                    tempTopic.topicSlateDocItemList instanceof Array
                ) {
                    //@ts-ignore
                    tempTopic.topicSlateDocItemList = JSON.stringify(tempTopic.topicSlateDocItemList)
                }
                tempTopicList.push(tempTopic);
            })
            _tempComDocInstance.topicList = tempTopicList;
            systemApi.updateProjectTopicList(_tempComDocInstance)
                .then(res => {
                    setSubmitLoading(false);
                    jumpToEditPage();
                })
                .catch(err => {
                    toastShort('error', '数据同步失败，请检查网络连接')
                })
        } else {
            const newTopicList = deepCloneV2(tree2List(topicTree)).map(ele => {
                delete ele.disabled;
                return ele;
            })
            onFinish(newTopicList);
            setIsModalOpen(false);
        }
    }

    const jumpToEditPage = () => {
        const { pathname, search } = routerLocation;
        localStorage.setItem("formEditPagePath", pathname + search);
        handleJumpEditPage(
            "/edit?docId=" + currentDocId + "&screen=topic&sidetab=allTopic"
        );
    }

    const handleCancel = () => {
        if (currentType == 'docId') {
            jumpToEditPage();
        } else {
            setIsModalOpen(false);
        }
    }

    const openModal = (params: { type: 'docId' | 'topicList', topicList?: TopicType[], docId?: string }) => {
        const {
            type,
            docId,
            topicList: originTopicList
        } = params;
        setCurrentDocId(docId);
        setCurrentType(type);
        setIsModalOpen(true);
        setPageLoading(true);
        if (type == 'docId') {
            queryDocProject(docId);
        } else {
            setTopicList(originTopicList);
            setPageLoading(false);
            let tempCheckedTopicIdList = originTopicList
                .filter(topic => topic.checked)
                .map(topic => topic.id);
            setTopicTreeCheckedNodeIdList(tempCheckedTopicIdList);
        }
    }

    const queryDocProject = (docId: string) => {
        setPageLoading(true);
        let params = {
            id: docId,
        };
        Promise.all([
            systemApi.getProjectBaseInfo(params),
            systemApi.queryDocExtraConfigInfo(params)
        ])
            .then(resList => {
                // console.log("res---->", resList);
                setPageLoading(false);
                let _tempComDocConfig: DocConfig = resList[1].data;
                let _tempComDocInstance: DocInstance = resList[0].data;
                let {
                    generatedDocConfig,
                    generatedDocInstance
                } = generateDocInstance(
                    resList[0].data,
                    _tempComDocConfig,
                    []
                );
                tempComDocInstance.current = _tempComDocInstance;
                tempComDocConfig.current = _tempComDocConfig;
                // console.log("generatedDocInstance--->", deepCloneV2(generatedDocInstance))
                setTopicList(generatedDocInstance.topicList);
                let tempCheckedTopicIdList = generatedDocInstance.topicList
                    .filter(topic => topic.checked)
                    .map(topic => topic.id);
                setTopicTreeCheckedNodeIdList(tempCheckedTopicIdList);
            })
            .catch(err => {
                // console.log("err---->", err)
                setPageLoading(false);
            })
    };


    const getNodeChildDeviceNodeCount = (node: TopicType): number => {
        let deviceNodeCount = 0;
        if (node.children) {
            node.children.forEach(subNode => {
                if (subNode.topicType == 'device') {
                    // if (subNode.checked) {
                    deviceNodeCount++;
                    // }
                } else {
                    const subNodeDeviceNodeTotalCount = getNodeChildDeviceNodeCount(subNode);
                    // console.log("subNodeDeviceNodeTotalCount--->", node.topicName, subNodeDeviceNodeTotalCount)
                    deviceNodeCount += subNodeDeviceNodeTotalCount;
                }
            })
        }
        return deviceNodeCount;
    };

    const getNodeChildDeviceNodeCheckedCount = (node: TopicType): number => {
        let deviceNodeCount = 0;
        if (node.children) {
            node.children.forEach(subNode => {
                if (subNode.topicType == 'device') {
                    if (subNode.checked) {
                        deviceNodeCount++;
                    }
                } else {
                    const subNodeDeviceNodeTotalCount = getNodeChildDeviceNodeCheckedCount(subNode);
                    // console.log("subNodeDeviceNodeTotalCount--->", node.topicName, subNodeDeviceNodeTotalCount)
                    deviceNodeCount += subNodeDeviceNodeTotalCount;
                }
            })
        }
        return deviceNodeCount;
    };

    //当前大纲的树形数据
    const topicTree = useMemo(() => {
        let _tree = generateTreeData(addTreePropertyForList(topicList));
        // _tree = filterTree(_tree, (node) => node.checked);
        let serialNumberList = [];
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                const childDeviceNodeCount = getNodeChildDeviceNodeCount(topic);
                const childDeviceNodeCheckedCount = getNodeChildDeviceNodeCheckedCount(topic);
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.treeLevel = level;
                topic.serialNumber = serialNumber;
                topic.childDeviceNodeCount = childDeviceNodeCount;
                topic.childDeviceNodeCheckedCount = childDeviceNodeCheckedCount;
            }
        })
        const topicTreeData: TopicType[] = deepCloneV2(_tree);
        return topicTreeData;
    }, [topicList, topicTreeCheckedNodeIdList])


    const arrayTreeFilter = (data, predicate, filterText) => {
        const nodes = data;
        if (!(nodes && nodes.length)) {
            return;
        }
        const newChildren = [];
        for (const node of nodes) {
            if (predicate(node, filterText)) {
                newChildren.push(node);
                node.children = arrayTreeFilter(node.children, predicate, filterText);
            } else {
                const subs = arrayTreeFilter(node.children, predicate, filterText);
                if ((subs && subs.length) || predicate(node, filterText)) {
                    node.children = subs;
                    newChildren.push(node);
                }
            }
        }
        return newChildren;
    }

    const autoHideTreeDeviceNode = () => {
        // console.log("autoHideTreeDeviceNode--->")
        // const treeNodeList = document.querySelectorAll('div.ant-tree-treenode');
        // console.log("treeNodeList--->", treeNodeList)
        // treeNodeList.forEach((div) => {
        //     const childWithDevice = div.querySelector('div[topic-type="device"]');
        //     if(childWithDevice){
        //         console.log("childWithDevice--->", childWithDevice)
        //         div.setAttribute('style', "display: none!important")
        //     }
        // })
    }

    useEffect(() => {
        autoHideTreeDeviceNode();
    }, [topicList])

    const filterFn = (data, filterText) => {
        if (!filterText) {
            return true;
        }
        return (
            new RegExp(filterText, "i").test(data.title)
        );
    }

    const expandedKeysFun = (treeData) => {
        if (treeData && treeData.length == 0) {
            return [];
        }
        let arr = [];
        const expandedKeysFn = (treeData) => {
            treeData.map((item, index) => {
                arr.push(item.key);
                if (item.children && item.children.length > 0) {
                    expandedKeysFn(item.children);
                }
            })
        }
        expandedKeysFn(treeData);
        return arr;
    }

    const onTopicSearchValueChange = (e: ChangeEvent<HTMLInputElement>) => {
        const newTopicSearchValue = getChangeEventValue(e);
        setTopicSearchValue(newTopicSearchValue);
        if (!isEmpty(newTopicSearchValue)) {
            let tempFilteredTopicTree = arrayTreeFilter(deepCloneV2(topicTree), filterFn, newTopicSearchValue);
            let tempFilteredTopicTreeExpandedKeys = expandedKeysFun(tempFilteredTopicTree);
            setFilteredTopicTree(tempFilteredTopicTree);
            setFilteredTreeExpandedKeys(tempFilteredTopicTreeExpandedKeys);
        }
    }

    const onDeviceTopicSearchValueChange = (e: ChangeEvent<HTMLInputElement>) => {
        setDeviceTopicSearchValue(getChangeEventValue(e));
    }

    const onTreeNodeCheckedChange = (checkedNodeIdList: string[]) => {
        let _tempTopicList = topicList;
        if (!isEmpty(topicSearchValue)) {
            const filteredTopicList: TopicType[] = tree2List([...filteredTopicTree]);
            const tempTopicTreeSelectNodeIdList = topicTreeSelectNodeIdList.current;
            const tempDiffTopicTreeSelectNodeIdList = [];
            tempTopicTreeSelectNodeIdList.forEach(id => {
                const find = filteredTopicList.find(node => {
                    return node.id == id;
                })
                if (!find) {
                    tempDiffTopicTreeSelectNodeIdList.push(id)
                }
            })
            const mergedTopicTreeSelectNodeIdList = tempDiffTopicTreeSelectNodeIdList.concat(checkedNodeIdList);
            setTopicTreeCheckedNodeIdList(mergedTopicTreeSelectNodeIdList);
            topicTreeSelectNodeIdList.current = mergedTopicTreeSelectNodeIdList;
            let _tempTopicList = topicList;
            _tempTopicList.forEach(topic => {
                if (mergedTopicTreeSelectNodeIdList.includes(topic.id)) {
                    topic.checked = true;
                } else {
                    topic.checked = false;
                }
            })
        } else {
            setTopicTreeCheckedNodeIdList(checkedNodeIdList);
            topicTreeSelectNodeIdList.current = checkedNodeIdList;
            _tempTopicList.forEach(topic => {
                if (checkedNodeIdList.includes(topic.id)) {
                    topic.checked = true;
                } else {
                    topic.checked = false;
                }
            })
        }
        _tempTopicList = deepCloneV2(_tempTopicList);
        setTopicList(_tempTopicList);
    };

    const onSelectCurrentTopicNode = (selectedKeys: string[]) => {
        const findTopicNode = topicList.find(ele => ele.id == selectedKeys[0]);
        if (findTopicNode && findTopicNode.topicType == 'device') {
            return toastShort('error', '项目节点不可继续添加下级节点')
        }
        setCurrentSelectedTopicNode(findTopicNode);
    };

    const onNodeContextMenu = (e, node) => {
        if (!isEmpty(topicSearchValue)) {
            toastShort('warning', '请退出搜索模式后重试');
            return false;
        }
        e.preventDefault();
        e.stopPropagation();
        setCurrentHighLightTopicNode(node)
        setCurrentSelectedTopicNode(node);
        contextMenuRef.current.showContextMenu(e);
    }

    const pureDeviceChildTopicKeys = useMemo(() => {
        let pureDeviceChildTopicKeyList: string[] = [];
        const topicTree = generateTreeData(topicList);
        dfsRecursive(topicTree, (node: TopicType) => {
            if(node.children.length && node.children.filter(subNode => subNode.topicType == 'device').length == node.children.length){
                pureDeviceChildTopicKeyList.push(node.id);
            }
        })
        return pureDeviceChildTopicKeyList;
    }, [topicList])

    const filterDisabledExpandKeys = (originExpandKeys: string[]): string[] => {
        return originExpandKeys.filter(key => !pureDeviceChildTopicKeys.includes(key))
    };

    const onTopicTreeNodeExpand = (expandedKeys: string[]) => {
        if (!isEmpty(topicSearchValue)) {
            setFilteredTreeExpandedKeys(filterDisabledExpandKeys(expandedKeys));
            return false;
        } else {
            setTopicTreeExpandedKeys(filterDisabledExpandKeys(expandedKeys));
        }
        autoHideTreeDeviceNode();
    }

    const switchTabKey = (newTabKey) => {
        setTabKey(newTabKey);
    }

    const adaptNodeSerialNumber = (node: TopicType) => {
        if (node.topicType == 'device') {
            return null;
        }
        return (
            <div
                className='topic-tree-node-extra'
            >
                {node.serialNumber}&nbsp;
            </div>
        )
    }

    const adaptNodeIcon = (node: TopicType) => {
        let nodeIcon = <i className='iconfont-1 ghzs-gray-shebei' />;
        switch (node.topicType) {
            case 'device':
                switch (node.deviceType) {
                    case 'S':
                        nodeIcon = <i className='iconfont-1 ghzs-gray-sheshi' />
                        break;
                    case 'X':
                        nodeIcon = <i className='iconfont-1 ghzs-gray-shebei' />

                        break;
                }
                break;
            case 'text':
                nodeIcon = <i className='iconfont-1 ghzs-gray-wenben' />
                break;
            default:
                break;
        }
        return (
            <div
                className='flex-row device-manage-tree-node-icon'
            >
                {nodeIcon}
            </div>
        );
    }

    const formatSearchTextForAllTopicTree = (originStr: string) => {
        try {
            if (isEmpty(topicSearchValue)) {
                return originStr;
            }
            let reg = new RegExp(topicSearchValue);
            let str = originStr.split(reg);
            let txt = [];
            if (str.length === 0 || str.length === 1) {
                return originStr
            }
            if (str.length > 0) {
                txt.push(<span key={'0-0'}>{str[0]}</span>);
            }
            txt.push(<span key={'0-1'} style={{ color: '#ff0000' }}>{topicSearchValue}</span>);
            if (str.length > 1) {
                txt.push(<span key={'0-2'}>{str[1]}</span>);
            }
            if (str.length >= 3) {
                for (let i = 2; i < str.length; i++) {
                    txt.push(<span key={'0-3'} style={{ color: '#ff0000' }}>{topicSearchValue}</span>);
                    txt.push(<span key={'0-4'}>{str[i]}</span>);
                }
            }
            return txt;
        } catch (e) {
            return originStr;
        }
    }

    const renderTopicTreeNode = (node: TopicType) => {
        return (
            <div
                className='device-manage-tree-node'
                //@ts-ignore
                topic-type={node.topicType}
                key={node.id}
                onContextMenu={(e) => onNodeContextMenu(e, node)}
                style={currentHighLightTopicNode && currentHighLightTopicNode.id == node.id ? { backgroundColor: '#f2f2f2' } : null}
            >
                <div className='flex-row device-manage-tree-node-content'>
                    {adaptNodeSerialNumber(node)}
                    {/* {adaptNodeIcon(node)} */}
                    <div className='single-line-text' style={{ maxWidth: 280, fontWeight: node.topicType == 'text' ? 'normal' : 'bold' }}>
                        {formatSearchTextForAllTopicTree(node.title)}
                    </div>
                    {
                        node.topicType == 'text' && node.childDeviceNodeCount && node.childDeviceNodeCount != node.directDeviceChildNodeCount ?
                            <Tooltip
                                title={"本节包含项目总数量"}
                            >
                                <div className='flex-row device-manage-tree-node-total-count'>{node.childDeviceNodeCount}</div>
                            </Tooltip>
                            :
                            null
                    }
                    {
                        node.topicType == 'text' && node.childDeviceNodeCheckedCount ?
                            <Tooltip
                                title={"本节选择项目总数量"}
                            >
                                <div className='flex-row device-manage-tree-node-count'>{node.childDeviceNodeCheckedCount}</div>
                            </Tooltip>
                            :
                            null
                    }
                </div>
            </div>
        );
    }

    const onCheckedChange = (e: any, node: TopicType) => {
        // const checked = getCheckBoxChangeEventValue(e);
        // let tempTopicList = topicList;
        // tempTopicList.forEach(deviceNode => {
        //     if (deviceNode.id == node.id) {
        //         deviceNode.checked = checked;
        //         deviceNode.pid = currentSelectedTopicNode.id;
        //     }
        // })
        // setTopicList([...tempTopicList]);
        // let topicListCheckedNodeIdList = topicTreeCheckedNodeIdList;
        // if (checked) {
        //     if (!topicListCheckedNodeIdList.includes(node.id)) {
        //         topicListCheckedNodeIdList.push(node.id);
        //     }
        // } else {
        //     if (topicListCheckedNodeIdList.includes(node.id)) {
        //         let findIndex = topicListCheckedNodeIdList.findIndex(key => key === node.id);
        //         topicListCheckedNodeIdList.splice(findIndex, 1);
        //     }
        // }
        // onTreeNodeCheckedChange([...topicListCheckedNodeIdList]);
        //V2实现
        const checked = getCheckBoxChangeEventValue(e);
        let tempTopicList = topicList;
        tempTopicList.forEach(deviceNode => {
            if (deviceNode.id == node.id) {
                deviceNode.checked = checked;
                // deviceNode.pid = currentSelectedTopicNode.id;
            }
        })
        setTopicList([...tempTopicList]);
        let topicListCheckedNodeIdList = topicTreeCheckedNodeIdList;
        if (checked) {
            if (!topicListCheckedNodeIdList.includes(node.id)) {
                topicListCheckedNodeIdList.push(node.id);
            }
        } else {
            if (topicListCheckedNodeIdList.includes(node.id)) {
                let findIndex = topicListCheckedNodeIdList.findIndex(key => key === node.id);
                topicListCheckedNodeIdList.splice(findIndex, 1);
            }
        }
        onTreeNodeCheckedChange([...topicListCheckedNodeIdList]);
    };

    const formatDeviceTopicSearchText = (originStr: string) => {
        try {
            if (isEmpty(deviceTopicSearchValue)) {
                return originStr;
            }
            let reg = new RegExp(deviceTopicSearchValue);
            let str = originStr.split(reg);
            let txt = [];
            if (str.length === 0 || str.length === 1) {
                return originStr
            }
            if (str.length > 0) {
                txt.push(<span key={'0-0'}>{str[0]}</span>);
            }
            txt.push(<span key={'0-1'} style={{ color: '#ff0000' }}>{deviceTopicSearchValue}</span>);
            if (str.length > 1) {
                txt.push(<span key={'0-2'}>{str[1]}</span>);
            }
            if (str.length >= 3) {
                for (let i = 2; i < str.length; i++) {
                    txt.push(<span key={'0-3'} style={{ color: '#ff0000' }}>{deviceTopicSearchValue}</span>);
                    txt.push(<span key={'0-4'}>{str[i]}</span>);
                }
            }
            return txt;
        } catch (e) {
            return originStr;
        }
    }

    const deviceNodeList = useMemo<TopicType[]>(() => {
        if (tabKey == 'all') {
            return topicList.filter(node => node.topicType == 'device' && node.title.includes(deviceTopicSearchValue)).map(node => {
                let findTextNode = topicList.find(textTopic => textTopic.id == node.pid);
                if (findTextNode) {
                    node.parentTextTopicTitle = findTextNode.topicName;
                }
                return node;
            });
        } else {
            let tempDeviceNodeList: TopicType[] = [];
            if (currentSelectedTopicNode) {
                dfsRecursive(topicTree, (node: TopicType, level: number) => {
                    if (node.id == currentSelectedTopicNode.id) {
                        // console.log("已经找到了---->", currentSelectedTopicNode.id);
                        dfsRecursive(node.children, (subNode: TopicType) => {
                            if (subNode.topicType == 'device') {
                                let findTextNode = topicList.find(textTopic => textTopic.id == subNode.pid);
                                if (findTextNode) {
                                    subNode.parentTextTopicTitle = findTextNode.topicName;
                                }
                                tempDeviceNodeList.push(subNode);
                            }
                        })
                    }

                })
            }
            return tempDeviceNodeList.filter(node => node.title.includes(deviceTopicSearchValue) || node.parentTextTopicTitle && node.parentTextTopicTitle.includes(deviceTopicSearchValue));
            // return topicList
            //     .filter(node => node.topicType == 'device' && currentSelectedTopicNode && node.pid == currentSelectedTopicNode.id
            //         // && node.checked
            //     )
            //     .filter(node => node.title.includes(deviceTopicSearchValue));
        }
    }, [tabKey, topicList, deviceTopicSearchValue, currentSelectedTopicNode]);

    const checkDeviceNodeIsChecked = (node: TopicType) => {
        if (tabKey == 'all') {
            return node.checked;
        } else {
            return node.checked;
        }
    };

    const checkDeviceNodeIsDisable = (node: TopicType) => {
        if (tabKey == 'all') {
            if (node.pid !== currentSelectedTopicNode.id && node.checked) {
                return true;
            } else {
                return false
            }
        }
        return false;
    }

    const renderDeviceNodeList = () => {
        if (deviceNodeList.length == 0 && tabKey == 'selected') {
            return (
                <div className='flex-col' style={{ width: '100%', height: '100%', justifyContent: 'center' }}>
                    <Empty description="当前选择的文本大纲暂未关联项目节点" />
                </div>
            )
        }
        return deviceNodeList.map(node => {
            return (
                <div
                    className='flex-row device-tree-node'
                    key={node.id}
                    title={node.title}
                >
                    <div className='flex-row device-tree-node-content'>
                        <Checkbox
                            checked={checkDeviceNodeIsChecked(node)}
                            onChange={e => onCheckedChange(e, node)}
                            disabled={checkDeviceNodeIsDisable(node)}
                        />
                        <div style={{ marginLeft: 3, marginRight: 3, opacity: checkDeviceNodeIsDisable(node) ? 0.52 : 1 }}>
                            {/* {adaptNodeIcon(node)} */}
                        </div>
                        <div className='single-line-text' style={{ width: 420, fontWeight: node.topicType == 'text' ? 'normal' : 'bold', opacity: checkDeviceNodeIsDisable(node) ? 0.52 : 1 }}>
                            {/* {checkDeviceNodeIsDisable(node) ? `[${node.parentTextTopicTitle}] > ` : null} */}
                            {
                                node.parentTextTopicTitle ?
                                    <span style={{ opacity: 0.52 }}>
                                        [{formatDeviceTopicSearchText(node.parentTextTopicTitle)}]
                                        {" > "}
                                    </span>
                                    :
                                    null
                            }
                            {formatDeviceTopicSearchText(node.title)}
                        </div>
                    </div>
                </div>
            )
        })
    };

    const onContextMenuClose = () => {
        setCurrentHighLightTopicNode(null);
    }


    const moveNode = (nodeList: TopicType[], targetId: string, direction: 'up' | 'down' | 'top' | 'bottom'): TopicType[] => {
        let findIndex = -1;
        if (nodeList.length == 0 || nodeList.length == 1) {
            return nodeList;
        }
        for (let i = 0; i < nodeList.length; i++) {
            if (nodeList[i].id == targetId) {
                findIndex = i;
                break;
            }
        }
        if (findIndex > -1) {
            const targetNodePid = nodeList[findIndex].pid;
            switch (direction) {
                case 'top':
                    let needToMoveDownNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i <= findIndex) {
                                needToMoveDownNodeIndexList.push(i)
                            }
                        }
                    }
                    if (needToMoveDownNodeIndexList[0] == findIndex) {
                        toastShort('warning', '该节点已置顶，请勿重复操作')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = needToMoveDownNodeIndexList.length - 1; i > 0; i--) {
                            const currentNodeIndex = needToMoveDownNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveDownNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'bottom':
                    let needToMoveUpNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i >= findIndex) {
                                needToMoveUpNodeIndexList.push(i)
                            }
                        }
                    }
                    if (needToMoveUpNodeIndexList[needToMoveUpNodeIndexList.length - 1] == findIndex) {
                        toastShort('warning', '该节点已置底，请勿重复操作')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = 0; i < needToMoveUpNodeIndexList.length; i++) {
                            const currentNodeIndex = needToMoveUpNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveUpNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'up':
                    if (
                        nodeList[findIndex - 1] &&
                        nodeList[findIndex - 1].pid == targetNodePid
                    ) {
                        let currentChildrenNodeIndexList: number[] = [];
                        for (let i = 0; i < nodeList.length; i++) {
                            if (nodeList[i].pid == targetNodePid) {
                                if (i <= findIndex) {
                                    currentChildrenNodeIndexList.push(i)
                                }
                            }
                        }
                        let _nodeList = nodeList;
                        _nodeList = swapListElements(_nodeList, currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 2], currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 1]);
                        toastShort('success', commonSuccessMsg)
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置顶，不可继续上移')
                    }
                    break;
                case 'down':
                    if (nodeList[findIndex + 1] && nodeList[findIndex + 1].pid == targetNodePid) {
                        toastShort('success', commonSuccessMsg)
                        const _nodeList = swapListElements(nodeList, findIndex, findIndex + 1);
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置底，不可继续下移')
                    }
                    break;
                default:
                    break;
            }
            return nodeList;
        } else {
            toastShort('error', '节点不存在，请您刷新页面重试！')
        }
    }

    const handleMoveCurrentSelectedNode = (moveType: 'up' | 'down' | 'top' | 'bottom') => {
        try {
            let _tempTopicList = topicList;
            _tempTopicList = moveNode(_tempTopicList, currentSelectedTopicNode.id, moveType);
            _tempTopicList = deepCloneV2(_tempTopicList);
            setTopicList(_tempTopicList);
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const [modal, contextHolder] = Modal.useModal();

    const handleDeleteCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: `确认删除此${currentSelectedTopicNode.topicType == 'device' ? '项目' : '大纲'}？`,
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToDeleteCurrentSelectedNode
        });
    }


    const confirmToDeleteCurrentSelectedNode = () => {
        try {
            let _tempTopicList = topicList;
            for (let i = 0; i < _tempTopicList.length; i++) {
                if (_tempTopicList[i].id == currentSelectedTopicNode.id) {
                    _tempTopicList.splice(i, 1);
                    break;
                }
            }
            _tempTopicList = deepCloneV2(_tempTopicList);
            setTopicList(_tempTopicList);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    /**
    * 当选择1级contextMenu之后
    * @param actionType 
    */
    const onPickerTreeNodeActionType = (actionType: TopicNodeActionType) => {
        setCurrentTreeNodeActionType(actionType);
        switch (actionType) {
            case 'AddDeviceChildNode':
                // if(Number(currentSelectedTopicNode.topicLevel) >= 6){
                //     return toastShort('error', '大纲节点最多不能超过6级')
                // }
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextChildNode':
                if (Number(currentSelectedTopicNode.topicLevel) >= 6) {
                    return toastShort('error', '大纲节点最多不能超过6级')
                }
                addTopicModalRef.current.openModal();
                break;
            case 'AddDevicePeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextPeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'MoveUp':
                handleMoveCurrentSelectedNode('up');
                break;
            case 'MoveDown':
                handleMoveCurrentSelectedNode('down');
                break;
            case 'MoveTop':
                handleMoveCurrentSelectedNode('top');
                break;
            case 'MoveBottom':
                handleMoveCurrentSelectedNode('bottom');
                break;
            case 'ReName':
                renameTopicModalRef.current.openModal(currentSelectedTopicNode.topicName);
                break;
            case 'Delete':
                handleDeleteCurrentSelectedNode();
                break;
            case 'UnChecked':
                handleUnCheckedCurrentSelectedNode();
                break;
            default:
                break;
        }
    }

    const handleUnCheckedCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: '确认从本文大纲中移除此节点吗？移除后您可在大纲配置中重新勾选',
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToUnCheckedCurrentSelectedNode,
        });
    }

    const findAllDescendants = (treeData: TopicType[], nodeId: string) => {
        const result = [];
        function findDescendants(node) {
            if (!node || !node.children) return;
            node.children.forEach(child => {
                result.push(child.id);
                findDescendants(child);
            });
        }

        function findNodeAndDescendants(nodes) {
            for (let i = 0; i < nodes.length; i++) {
                if (nodes[i].id === nodeId) {
                    findDescendants(nodes[i]);
                    break;
                }
                if (nodes[i].children) {
                    findNodeAndDescendants(nodes[i].children);
                }
            }
        }
        findNodeAndDescendants(treeData);
        return result;
    }

    const findTreePathByTargetNodeIdList = (treeData: TopicType[], nodeId: string) => {
        const map = new Map();
        // 建立每个节点与其父节点的映射
        function buildMap(node, parentId = null) {
            if (!node) return;
            map.set(node.id, parentId);
            if (node.children) {
                node.children.forEach(child => buildMap(child, node.id));
            }
        }
        // 遍历树数据，建立映射
        treeData.forEach(node => buildMap(node));
        // 从指定节点回溯到根节点
        const path = [];
        let currentId = nodeId;
        while (currentId !== null) {
            path.push(currentId);
            currentId = map.get(currentId);
        }
        return path.reverse(); // 反转数组，使其从根节点开始
    }

    const confirmToUnCheckedCurrentSelectedNode = () => {
        try {
            // //需要直接取消勾选的节点
            let needToUnCheckedIdList = findAllDescendants(topicTree, currentSelectedTopicNode.id);
            // //需要取消勾选的节点(如果此节点是勾选的话);
            let needToUnCheckedIfNodeChecedIdList = findTreePathByTargetNodeIdList(topicTree, currentSelectedTopicNode.id);
            const tempTopicTreeData = generateTreeData(topicList);
            dfsRecursive(tempTopicTreeData, (node: TopicType) => {
                if (node.id == currentSelectedTopicNode.id) {
                    node.checked = false;
                }
                if (needToUnCheckedIdList.includes(node.id)) {
                    node.checked = false;
                }
                if (needToUnCheckedIfNodeChecedIdList.includes(node.id)) {
                    node.checked = false;
                }
            })
            setTopicList(deepCloneV2(tree2List(tempTopicTreeData)));
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }


    const deleteNode = (key, data) => {
        data.forEach((item, index, arr) => {
            if (item.key === key) {
                arr.splice(index, 1);
            } else if (item.children) {
                deleteNode(key, item.children);
            }
        });
    };

    const updateNodePid = (node: TopicType, pid: string): TopicType => {
        node.pid = pid;
        if (node.children) {
            node.children.forEach(child => updateNodePid(child, node.key));
        }
        return node;
    };

    /**
 * 添加指定树节点下的子节点
 * @param tree 
 * @param list 
 * @param targetNodeId 
 */
    const insertChildNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        tree.forEach(node => {
            if (node.id == targetNodeId) {
                list && list.length && list.forEach(item => {
                    item.pid = targetNodeId;
                })
                if (node.children && node.children.length) {
                    node.children = node.children.concat(list);
                } else {
                    node.children = list;
                }
            } else if (node.children) {
                insertChildNodeListToTree(node.children, list, targetNodeId)
            }
        })
    }

    const insertTopPeerNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        let findTopTagetNodeIndex = -1;
        tree.forEach((node, nodeIndex) => {
            if (node.id == targetNodeId) {
                findTopTagetNodeIndex = nodeIndex;
            }
        })
        list.forEach(item => {
            item.pid = '0';
        })
        let tempTreeData = tree;
        if (findTopTagetNodeIndex > -1) {
            const lastArr = tempTreeData.splice(findTopTagetNodeIndex + 1, tree.length - 1);
            tempTreeData = tempTreeData.concat(list).concat(lastArr)
        }
        return tempTreeData;
    }

    const insertPeerNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        list.forEach(topic => {
            topic.wordParagraphList = [];
        })
        tree.forEach((node, index, array) => {
            if (node.children && node.children.length) {
                let targetIndex = node.children.findIndex(subNode => subNode.id === targetNodeId);
                if (targetIndex !== -1) {
                    list.forEach(item => {
                        item.pid = node.id;
                    });
                    node.children.splice(targetIndex + 1, 0, ...list);
                } else {
                    insertPeerNodeListToTree(node.children, list, targetNodeId);
                }
            }
        });
    };

    /**
  * 第一步构造好树结构
  * 第二步把节点添加到树中
  * 第三步把树结构转换成topicList列表结构
  * 第四步触发树节点自动转换
  * @param newTopic 
  */
    const onChangeTopic = (newTopic: TopicType, originTopic: TopicType) => {
        try {
            let _tempTreeData = topicTree;
            let _checkedTopicIdList = topicTreeCheckedNodeIdList;
            if (originTopic) {
                deleteNode(originTopic.id, _tempTreeData)
            }
            newTopic.checked = true;
            newTopic.childrenDeviceTopicListLength = 0;
            _checkedTopicIdList.push(newTopic.id);
            setTopicTreeCheckedNodeIdList([..._checkedTopicIdList]);
            let newTopicNodeList = [newTopic];
            switch (currentTreeNodeActionType) {
                case 'AddDeviceChildNode':
                    insertChildNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    break;
                case 'AddTextChildNode':
                    insertChildNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    break;
                case 'AddDevicePeerNode':
                    if (currentSelectedTopicNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    }
                    break;
                case 'AddTextPeerNode':
                    if (currentSelectedTopicNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    }
                    break;
                default:
                    break;
            }
            let tempTopicNodeId: string = '';
            let tempTopicTreeCheckedNodeIdList = topicTreeCheckedNodeIdList;
            let testNodeId = newTopic.id;
            if (newTopic.checked) {
                tempTopicTreeCheckedNodeIdList.push(newTopic.id);
            } else {
                dfsRecursiveFromInner(_tempTreeData, (node: TopicType) => {
                    if (node.id == testNodeId) {
                        tempTopicNodeId = node.pid;
                    }
                    if (node.id == tempTopicNodeId) {
                        node.checked = false;
                        let findIndex = -1;
                        for (let i = 0; i < tempTopicTreeCheckedNodeIdList.length; i++) {
                            findIndex = i;
                            break;
                        }
                        if (findIndex != -1) {
                            tempTopicTreeCheckedNodeIdList.splice(findIndex, 1);
                        }
                        tempTopicNodeId = node.pid;
                    }
                })
            }
            const halfCheckeNodeList: string[] = findHalfCheckedKeys(_tempTreeData, tempTopicTreeCheckedNodeIdList);
            setTopicTreeCheckedNodeIdList(tempTopicTreeCheckedNodeIdList.concat(halfCheckeNodeList))
            const _tempTopicList = [...tree2List(_tempTreeData)];
            setTopicList(_tempTopicList);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const _onReNameFinish = (newName: string) => {
        let _tempTopicList = topicList;
        _tempTopicList.forEach(topic => {
            if (topic.id == currentSelectedTopicNode.id) {
                topic.topicName = newName;
            }
        })
        _tempTopicList = deepCloneV2(_tempTopicList);
        setTopicList(_tempTopicList)
    }

    const handleAddDeviceNode = () => {
        onPickerTreeNodeActionType('AddDeviceChildNode')
    };

    return (
        <Modal
            title={"确定规划大纲与设施设备"}
            open={isModalOpen}
            onOk={handleConfirm}
            onCancel={handleCancel}
            okText={"确定"}
            cancelText={currentType === 'topicList' ? "取消" : "跳过"}
            width={980}
            maskClosable={false}
            confirmLoading={submitLoading}
            centered
        >
            <div className="flex-row custom-modal-container" style={{ height: 900, width: '100%', flexDirection: 'row', justifyContent: 'space-between' }}>
                <div className="flex-col topic-manage-modal-side">
                    <Search
                        placeholder={'搜索大纲库关键字'}
                        size={'middle'}
                        style={{ marginBottom: 10, width: 420 }}
                        allowClear
                        value={topicSearchValue}
                        onChange={onTopicSearchValueChange}
                    />
                    <div style={{ width: '100%', height: 630, overflowY: 'auto', overflowX: 'auto' }}>
                        <Tree
                            // style={{ width: 370 }}
                            showLine
                            defaultExpandAll={false}
                            checkedKeys={topicTreeCheckedNodeIdList}
                            switcherIcon={<DownOutlined />}
                            onCheck={onTreeNodeCheckedChange}
                            checkable
                            //@ts-ignore
                            titleRender={renderTopicTreeNode}
                            //@ts-ignore
                            treeData={isEmpty(topicSearchValue) ? topicTree : filteredTopicTree}
                            selectedKeys={currentSelectedTopicNode ? [currentSelectedTopicNode.id] : []}
                            onExpand={onTopicTreeNodeExpand}
                            expandedKeys={isEmpty(topicSearchValue) ? topicTreeExpandedKeys : filteredTreeExpandedKeys}
                            onSelect={onSelectCurrentTopicNode}
                            // height={630}
                            blockNode
                        />
                    </div>
                </div>
                <div className='flex-col' style={{ height: '100%', color: '#0f6432', justifyContent: 'center', alignItems: 'center' }}>
                    <PartitionOutlined style={{ fontSize: 24 }} />
                </div>
                {
                    currentSelectedTopicNode ?
                        <div className="flex-col topic-manage-modal-side">
                            <div className="flex-row topic-manage-tab-bar">
                                <div className='flex-row' style={{ flex: 1 }}>
                                    <Tooltip title={`${currentSelectedTopicNode && currentSelectedTopicNode.topicName}大纲节点下包含的所有项目清单`}>
                                        <div onClick={() => switchTabKey('selected')} className="flex-row topic-manage-tab-item">
                                            本节项目
                                            <QuestionCircleOutlined style={{ marginLeft: 3 }} />
                                        </div>
                                    </Tooltip>
                                    {/* <div onClick={() => switchTabKey('all')} className="flex-row topic-manage-tab-item">
                                        所有项目
                                    </div> */}
                                </div>
                                <Tooltip title={"为左侧选择大纲添加下级设施/设备"}>
                                    <Button
                                        style={{ marginRight: 10 }}
                                        icon={<PlusCircleTwoTone />}
                                        type={'text'}
                                        onClick={handleAddDeviceNode}
                                        disabled={!currentSelectedTopicNode}
                                    ></Button>
                                </Tooltip>
                                <div className='topic-manage-tab-bar-bottom-line' style={{ left: tabKey == 'selected' ? 8 : 76, width: tabKey == 'selected' ? 80 : 60 }}></div>
                            </div>
                            <Search
                                placeholder={'搜索项目(设施/设备)关键字'}
                                size={'middle'}
                                style={{ marginBottom: 10, width: 420, marginTop: 10 }}
                                allowClear
                                value={deviceTopicSearchValue}
                                onChange={onDeviceTopicSearchValueChange}
                            />
                            <div
                                className='topic-manage-modal-side-content'
                            >
                                {renderDeviceNodeList()}
                            </div>
                        </div>
                        :
                        <div className="flex-col topic-manage-modal-side" style={{ justifyContent: 'center' }}>
                            <Empty description="请先点击左侧大纲节点" />
                        </div>
                }
                <LoadingWapper loading={pageLoading} />
            </div>
            <TopicTreeContextMenu
                ref={contextMenuRef}
                currentScreen={'allTopic'}
                onContextMenuClose={onContextMenuClose}
                currentTopicNode={currentSelectedTopicNode}
                onPickerActionType={onPickerTreeNodeActionType}
                allowOption={'just-text'}
            />
            <AddTopicMoal
                ref={addTopicModalRef}
                currentTopicNode={currentSelectedTopicNode}
                currentTreeNodeActionType={currentTreeNodeActionType}
                onFinish={onChangeTopic}
            />
            <ReNameTopicModal
                ref={renameTopicModalRef}
                onFinish={_onReNameFinish}
            />
        </Modal>
    )
}


export default forwardRef(DeviceNodeManageModalV2);
